//
//  BlocklyVC.m
//  blocklyios
//
//  Created by steward on 2018/11/25.
//  Copyright © 2018 szltech. All rights reserved.
//

#import "BlocklyVC.h"
#import <WebKit/WebKit.h>
#import "Masonry.h"
#import "ViewController.h"
#import "MBProgressHUD.h"
#import "ConstantUtils.h"

@interface BlocklyVC ()<WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler>
@property (strong, nonatomic) IBOutlet UIImageView *splashImg;
@property (strong, nonatomic) WKWebView *webview;
@property (strong, nonatomic) IBOutlet UIView *loadingLayout;
@property (strong, nonatomic) IBOutlet UIProgressView *progressBar;
//将需要发送的16进制字符串分割成数组
@property (strong, nonatomic) IBOutlet UIImageView *imgLoadingClose;
@property (strong, nonatomic) NSMutableArray<NSString *> *wholeArray;
//发送位置
@property int position;
//正在发送的字符串
@property (strong, nonatomic) NSString *sendStr;
//真正发送的字符串长度
@property NSUInteger sendDataLen;
//是否终止发送数据
@property BOOL isStop;
//调试模式发送和下载模式发送区分flag
@property BOOL isDebug;

@property (strong, nonatomic) MBProgressHUD *hud;
@end

@implementation BlocklyVC

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initWebView];
    [self loadLocalHtml];
    [self initBlueTooth];
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.baby && self.mPeripheral) {
        //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态。
        [self connectDevice];
    }
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    if (self.baby) {
        [self.baby cancelAllPeripheralsConnection];
    }
}

-(void)initBlueTooth {
    [super initBlueTooth];
    [self babyDelegate];
}

-(void)connectDevice {
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    [super connectDevice];
}

-(void)babyDelegate {
    @weakify(self);
    [self.baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
        NSLog(@"设备：%@--连接成功",peripheral.name);
    }];
    
    //设置设备连接失败的委托
    [self.baby setBlockOnFailToConnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        NSLog(@"设备：%@--连接失败",peripheral.name);
    }];
    
    //设置设备断开连接的委托
    [self.baby setBlockOnDisconnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        NSLog(@"设备：%@--断开连接",peripheral.name);
        @strongify(self);
        [self connectDevice];
    }];
    
    //设置发现设备的Services的委托
    [self.baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) {
    }];
    //设置发现设service的Characteristics的委托
    [self.baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        @strongify(self);
        if ([service.UUID.UUIDString isEqualToString:@"FEE0"]) {
            for (CBCharacteristic *c in service.characteristics) {
                if ([c.UUID.UUIDString isEqualToString:@"FEE1"]) {
                    @strongify(self);
                    self.writeCharacteristic = c;
                    [self.baby notify:self.mPeripheral characteristic:self.writeCharacteristic block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
                        //接收到值会进入这个方法
                        if (!error) {
                            if (!self.isStop) {
                                if (self.sendDataLen > 0) {
                                    NSLog(@"new value %@",[ConstantUtils data2Str:characteristics.value]);
                                    [self performSelector:@selector(onSend) withObject:nil afterDelay:0.05];
                                }
                            }
                            
                        }
                    }];
                    break;
                }
            }
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        } else {
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        }
    }];
    //设置读取characteristics的委托
    [self.baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
    }];
    //设置发现characteristics的descriptors的委托
    [self.baby setBlockOnDiscoverDescriptorsForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
    }];
    //设置读取Descriptor的委托
    [self.baby setBlockOnReadValueForDescriptors:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
    }];
    
    //写Characteristic成功后的block
    [self.baby setBlockOnDidWriteValueForCharacteristic:^(CBCharacteristic *characteristic, NSError *error) {
    }];
}

-(void)initWebView {
    WKWebViewConfiguration *con = [WKWebViewConfiguration.alloc init];
    self.webview = [WKWebView.alloc initWithFrame:CGRectZero configuration:con];
    self.webview.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
    [self.webview.scrollView setUserInteractionEnabled:YES];
    [self.webview.scrollView setBounces:NO];
    [self.webview setAllowsLinkPreview:NO];
    [self.view addSubview:self.webview];
    [self.webview mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.bottom.top.mas_equalTo(self.view);
    }];
    [self.view bringSubviewToFront:self.splashImg];
    [self.view bringSubviewToFront:self.loadingLayout];
    self.webview.navigationDelegate = self;
    self.webview.UIDelegate = self;
    self.webview.configuration.userContentController = [WKUserContentController.alloc init];
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:WRITE_TO_DEVICE];
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:WRITE_DEBUG_STR_TO_DEVICE];
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:SAVE_STR];
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:DELETE_STR];
    [self.webview.configuration.userContentController addScriptMessageHandler:self name:GET_STR];
    [self clickImgLoadingCloseEvent];
    self.isStop = NO;
    
    //splash延时两秒后展示主界面
    [self performSelector:@selector(displayMainPage) withObject:nil afterDelay:2];
}

- (void)displayMainPage {
    [self.splashImg setHidden:YES];
}

-(void)clickImgLoadingCloseEvent {
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
    [[tap rac_gestureSignal] subscribeNext:^(id x) {
        [self hideProgressHud];
        self.isStop = YES;
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
    }];
    [self.imgLoadingClose addGestureRecognizer:tap];
}

-(void)loadLocalHtml {
    NSString *mainBundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *basePath = [NSString stringWithFormat:@"%@/blocklyhtml/demos/mydemo",mainBundlePath];
    NSURL *baseUrl = [NSURL fileURLWithPath:basePath isDirectory:YES];
    NSString *htmlPath = [NSString stringWithFormat:@"%@/DemoTry.html",basePath];
    NSString *htmlString = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];
    [self.webview loadHTMLString:htmlString baseURL:baseUrl];
}

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
    
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    
    
    [self presentViewController:alertController animated:YES completion:nil];
}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:WRITE_TO_DEVICE]) {
        self.isDebug = NO;
        [self writeToDevice:message];
    } else if ([message.name isEqualToString:WRITE_DEBUG_STR_TO_DEVICE]) {
        self.isDebug = YES;
        [self writeToDevice:message];
    } else if ([message.name isEqualToString:SAVE_STR]) {
        [self handleSaveStr:message];
        
    } else if ([message.name isEqualToString:DELETE_STR]) {
        [self handleDeleteStr:message];
        
    } else if ([message.name isEqualToString:GET_STR]) {
        [self handleGetStr:message];
    }
}

-(void)handleGetStr:(WKScriptMessage *)message {
    NSDictionary *dict = (NSDictionary *)message.body;
    NSString *key = dict[@"key"];
    NSString *value = [ConstantUtils getStr:key];
//    if (value.length) {
        NSString *jsCode = [NSString stringWithFormat:@"DemoApp.programList.onGetKey('%@', '%@')", key, value];
        [self.webview evaluateJavaScript:jsCode completionHandler:^(id _Nullable data, NSError * _Nullable error) {
            if (error) {
                NSLog(@"错误:%@", error.localizedDescription);
            }
        }];
//    }
}

-(void)handleDeleteStr:(WKScriptMessage *)message {
    NSDictionary *dict = (NSDictionary *)message.body;
    NSString *key = dict[@"key"];
    [ConstantUtils deleteStr:key];
}

-(void)handleSaveStr:(WKScriptMessage *)message {
    NSDictionary *dict = (NSDictionary *)message.body;
    NSString *key = dict[@"key"];
    NSString *value = dict[@"value"];
    [ConstantUtils saveStr:key value:value];
}

/**
 * 发送命令或调试命令
 * @param message 发送的消息体
 */
-(void)writeToDevice: (WKScriptMessage *)message {
    NSDictionary *dict = (NSDictionary *)message.body;
    NSString *code = dict[@"code"];
    if (self.mPeripheral && self.writeCharacteristic) {
        NSString *wholeStr = @"";
        if (self.isDebug) {
            wholeStr = [ConstantUtils getDebugSendStr:code];
        } else {
            wholeStr = [ConstantUtils getSendStr:code];
        }
        self.wholeArray= [NSMutableArray arrayWithArray:[wholeStr componentsSeparatedByString:@"0a"]];
        for (int i = 0; i < self.wholeArray.count; i++) {
            NSString *str = self.wholeArray[i];
            if ([str isEqualToString:@"03"] || [str isEqualToString:@"04"]) {
                [self.wholeArray replaceObjectAtIndex:i withObject:str];
            } else {
                [self.wholeArray replaceObjectAtIndex:i withObject:[str stringByAppendingString:@"0d0a"]];
            }
        }
        [self showProgressHud];
        self.position = 0;
        self.isStop = NO;
        [self delaySend];
    } else {
        ViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController"];
        @weakify(self);
        vc.fetchDevice = ^(CBPeripheral *peripheral) {
            @strongify(self);
            self.mPeripheral = peripheral;
            [self connectDevice];
        };
        [self.navigationController pushViewController:vc animated:YES];
    }
}

-(void)delaySend {
    int time;
    if (self.isDebug) {
        if (self.position == 0) {
            time = 1;
        } else if (self.position == 1) {
            time = 2500;
        } else if (self.position == 2) {
            time = 1000;
        } else if (self.position == 3) {
            time = 2500;
        } else {
            time = 1000;
        }
    } else {
        if (self.position == 0) {
            time = 1;
        } else if (self.position == 1) {
            time = 2500;
        } else {
            time = 1000;
        }
    }
    if (!self.isStop) {
        [self performSelector:@selector(delaySendAction) withObject:nil afterDelay:time / 1000];
    }
}

-(void)delaySendAction {
    
    NSLog(@"positon = %i", self.position);
    if (self.position >= self.wholeArray.count) {
        NSLog(@"error now");
    }
    if (self.position < self.wholeArray.count) {
        self.sendStr = self.wholeArray[self.position];
        self.sendDataLen = self.sendStr.length;
        [self onSend];
    }
}

-(void)onSend {
    if (self.sendDataLen > 20) {
        NSString *partStr = [self.sendStr substringWithRange:NSMakeRange(0, 20)];
        [self writeDataToDevice:partStr];
        self.sendDataLen -=20;
        self.sendStr = [self.sendStr substringFromIndex:20];
    } else {
        NSString *partStr = self.sendStr;
        self.sendStr = @"";
        self.sendDataLen = 0;
        [self writeDataToDevice:partStr];
        self.position++;
        self.progressBar.progress = (float)self.position / self.wholeArray.count;
        if (self.position < self.wholeArray.count) {
            [self delaySend];
        } else {
            [self hideProgressHud];
            [self whenDismissDialog];
        }
    }
}

-(void)whenDismissDialog {
    NSString *jsCode = @"javascript:DemoApp.showLoadSuccess()";
    [self.webview evaluateJavaScript:jsCode completionHandler:^(id _Nullable data, NSError * _Nullable error) {
        if (error) {
            NSLog(@"错误:%@", error.localizedDescription);
        }
    }];
}

-(void)showProgressHud {
    self.loadingLayout.hidden = NO;
}

-(void)hideProgressHud {
    self.progressBar.progress = 0;
    self.loadingLayout.hidden = YES;
}

@end
